//
//  BCJSONDecoder.swift
//  Pods
//
//  Created by Basic. on 2019/7/3.
//

import Foundation

public class BCJSONDecoder: CleanJSONDecoder {
    
    /// data 序列化  model
    /// - Parameters:
    ///   - type: model的类型
    ///   - data: data数据
    ///   - mapper: 自定义映射器，可以只映射指定 coding path 的 key
    /// - Returns: description
    static func bc_decode<T : Decodable>(_ type: T.Type,_ data: Data, _ mapper:[CodingPath: String]) -> T? {
        let decoder = BCJSONDecoder()
        decoder.keyDecodingStrategy = .mapper(mapper)
        return decoder.bc_decode(type, data)
    }

    /// data 序列化  model
    ///
    /// - Parameters:
    ///   - type: model的类型
    ///   - data: data数据
    /// - Returns: return value description
    public func bc_decode<T : Decodable>(_ type: T.Type,_ data: Data) -> T? {
        var result: T?
        do {
            result = try self.decode(type, from: data)
        } catch  {
            #if DEBUG
            NSLog("[bcmodel] %@", error.localizedDescription)
            #endif
        }
        return result
    }
    
    /// 字典转模型
    ///
    /// - Parameters:
    ///   - type: 模型
    ///   - dic: 字典
    /// - Returns: 模型
    public func bc_decode<T : Decodable>(_ type: T.Type,_ dic: [String:Any]?) -> T? {
        var result: T?
        do {
            let data = try JSONSerialization.data(withJSONObject: dic ?? [:], options: .prettyPrinted)
            result = try self.decode(type, from: data)
        } catch  {
            #if DEBUG
            NSLog("[bcmodel] %@", error.localizedDescription)
            #endif
        }
        return result
    }
    
    /// json数组转模型数组
    /// - Parameters:
    ///   - type: 模型
    ///   - array: 数组
    /// - Returns: 模型数组
    static public func bc_decode<T>(_ type:T.Type, _ array:[[String:Any]]) -> [T]? where T:Codable {
        
        guard let jsonData = try? JSONSerialization.data(withJSONObject: array, options: []) else {
            return nil
        }
        guard let result = try? JSONDecoder.init().decode([T].self, from: jsonData) else {
            return nil
        }
        return result
    }
}
